import React, {createContext, CSSProperties, FC, FunctionComponentElement, ReactNode, useState} from 'react'
import classNames from "classnames";
import {IMenuItemProps} from "./menuItem";


type MenuMode = 'horizontal' | 'vertical' // 水平或者垂直
type SelectCallback = (selectIndex: string) => void

export interface IMenuProps {
    /*默认选中菜单*/
    defaultIndex?: string
    className?: string
    mode?: MenuMode
    style?: CSSProperties

    /**
     * 选中事件
     * @param selectIndex
     */
    onSelect?: SelectCallback
}

interface IMenuContext {
    index: string
    onSelect?: SelectCallback
    mode?: MenuMode
}

// 使用useContext传递参数
export const MenuContext = createContext<IMenuContext>({index: '0'})

/**
 * 判断传进来的组件一定是MenuItem,否则不渲染。
 * @param children
 */
const renderChildren = (children: ReactNode) => {
  return React.Children.map(children, (child, index) => {
    // 转换成react 组件
    const elem = child as FunctionComponentElement<IMenuItemProps>
    const {displayName} = elem.type
    if (displayName === 'MenuItem' || displayName==='SubMenu') {
      // 克隆一份组件，并且设置props
      return React.cloneElement(elem, {
        index: `${index}`
      })
    } else {
      console.warn("Warning: Menu has a child which is not a MenuItem component")
    }
  })
}


const Menu: FC<IMenuProps> = (props) => {
  const {defaultIndex, className, mode, style, onSelect, children} = props
  const [currentIndex, setCurrentIndex] = useState(defaultIndex || '0');

  const classes = classNames("viking-menu", className, {
    'menu-vertical': mode === "vertical",
    'menu-horizontal': mode === "horizontal",
  })

  // menuItem选中点击事件
  const menuItemHandleClick = (index: string) => {
    setCurrentIndex(index)
    if (onSelect) {
      onSelect(index)
    }
  }

  // 传递参数给MenuItem子组件
  const propsContext: IMenuContext = {
    index: currentIndex,
    onSelect: menuItemHandleClick,
    mode:mode
  }

  return (

    <ul className={classes} style={style} data-testid={"test-menu"}>
      <MenuContext.Provider value={propsContext}>
        {renderChildren(children)}
      </MenuContext.Provider>
    </ul>
  )
}

Menu.defaultProps = {
  defaultIndex: '0',
  mode: 'horizontal'
}

export default Menu;
